{
xen_kexec_range_t range;
struct resource *res;
- int err, k = 0;
+ int k = 0;
if (!is_initial_xendomain())
return;
range.range = KEXEC_RANGE_MA_CPU;
range.nr = k;
- /*
- * Anything other than EINVAL or success indictates
- * that we are not running on a hypervisor which
- * supports kexec.
- */
- err = HYPERVISOR_kexec_op(KEXEC_CMD_kexec_get_range, &range);
- if (err == -EINVAL)
+ if(HYPERVISOR_kexec_op(KEXEC_CMD_kexec_get_range, &range))
break;
- else if (err)
- return;
k++;
}
+ if (k == 0)
+ return;
+
xen_max_nr_phys_cpus = k;
/* allocate xen_phys_cpus */
xen_phys_cpus = alloc_bootmem_low(k * sizeof(struct resource));
- BUG_ON(!xen_phys_cpus);
+ BUG_ON(xen_phys_cpus == NULL);
/* fill in xen_phys_cpus with per-cpu crash note information */
range.nr = k;
if (HYPERVISOR_kexec_op(KEXEC_CMD_kexec_get_range, &range))
- BUG();
+ goto err;
res = xen_phys_cpus + k;
range.range = KEXEC_RANGE_MA_XEN;
if (HYPERVISOR_kexec_op(KEXEC_CMD_kexec_get_range, &range))
- BUG();
+ goto err;
xen_hypervisor_res.name = "Hypervisor code and data";
xen_hypervisor_res.start = range.start;
range.range = KEXEC_RANGE_MA_CRASH;
if (HYPERVISOR_kexec_op(KEXEC_CMD_kexec_get_range, &range))
- BUG();
+ return;
if (range.size) {
crashk_res.start = range.start;
crashk_res.end = range.start + range.size - 1;
}
+
+ return;
+
+ err:
+ /*
+ * It isn't possible to free xen_phys_cpus this early in the
+ * boot. Since failure at this stage is unexpected and the
+ * amount is small we leak the memory.
+ */
+ xen_max_nr_phys_cpus = 0;
+ return;
}
void xen_machine_kexec_register_resources(struct resource *res)